/* 
    take, first, takeUntil, concatAll 
*/

/* 
    take
    take 是一个很简单的operator，顾名思义就是取前几个元素后就结束，范例如下
    这里可以看到我们的 source 原本是会发出无限个元素的，但这里我们用 take(3) 就会只取前3 个元素，取完后就直接结束(complete)
*/

var source = Rx.Observable.interval(1000);
var example = source.take(3);

example.subscribe({
    next: (value) => { console.log(value); },
    error: (err) => { console.log('Error: ' + err); },
    complete: () => { console.log('complete'); }
});
// 0
// 1
// 2
// complete
/* 
    source : -----0-----1-----2-----3--..
                take(3)
    example: -----0-----1-----2|
*/

/* 
    first
    first 会取observable 送出的第1 个元素之后就直接结束，行为跟take(1) 一致。
*/

var source1 = Rx.Observable.interval(1000);
var example1 = source1.first();

example1.subscribe({
    next: (value) => { console.log(value); },
    error: (err) => { console.log('Error: ' + err); },
    complete: () => { console.log('complete'); }
});

// 0
// complete


/* 
    takeUntil
    在实务上takeUntil 很常使用到，他可以在某件事情发生时，让一个observable 直送出完成(complete)讯息，范例如下
    这里我们一开始先用 interval 建立一个observable，这个observable 每隔1 秒会送出一个从0 开始递增的数值，
    接着我们用takeUntil，传入另一个observable。
    当 takeUntil 传入的observable 发送值时，原本的observable 就会直接进入完成(complete)的状态，并且发送完成讯息。也就是说上面这段程式码的行为，
    会先每1 秒印出一个数字(从0 递增)直到我们点击body 为止，他才会送出complete 讯息。
*/
var source2 = Rx.Observable.interval(1000);
var click = Rx.Observable.fromEvent(document.body, 'click');
var example2 = source2.takeUntil(click);     
   
example2.subscribe({
    next: (value) => { console.log(value); },
    error: (err) => { console.log('Error: ' + err); },
    complete: () => { console.log('complete'); }
});
// 0
// 1
// 2
// 3
// complete (點擊body了

/*  concatAll
    有时我们的Observable 送出的元素又是一个observable，就像是二维阵列，阵列里面的元素是阵列，这时我们就可以用 
    concatAll 把它摊平成一维阵列，大家也可以直接把concatAll 想成把所有元素concat 起来。
    这个范例我们每点击一次body 就会立刻送出1,2,3，如果用Marble diagram 表示则如下
    click  : ------c------------c--------

        map(e => Rx.Observable.of(1,2,3))

    source : ------o------------o--------
                    \            \
                    (123)|       (123)|

                    concatAll()

    example: ------(123)--------(123)------------
    这里可以看到sourceobservable 内部每次发送的值也是observable，这时我们用concatAll 就可以把source 摊平成example。

    这里需要注意的是 concatAll 会处理source 先发出来的observable，必须等到这个observable 结束，才会再处理下一个source 发出来的observable，
    让我们用下面这个范例说明。
*/

var click2 = Rx.Observable.fromEvent(document.body, 'click');
var source3 = click2.map(e => Rx.Observable.of(1,2,3));

var example3 = source3.concatAll();
example3.subscribe({
    next: (value) => { console.log(value); },
    error: (err) => { console.log('Error: ' + err); },
    complete: () => { console.log('complete'); }
});

/* 有了以上操作符，我们就可以搭配fromEvent takeUntil concatAll 陪护实现一个拖拉的功能 ，详情见demo目录 */